package cn.hinglo.gameclaw.admin.service;

import cn.hinglo.gameclaw.admin.dao.OrderDao;
import cn.hinglo.gameclaw.data.entity.Result;
import cn.hinglo.gameclaw.data.utils.FieldUtils;
import cn.hinglo.gameclaw.data.utils.IdUtils;
import cn.hinglo.gameclaw.data.utils.ResultUtils;
import cn.hinglo.gameclaw.user.bean.GrabNote;
import cn.hinglo.gameclaw.user.bean.Orders;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.hinglo.gameclaw.data.utils.CheckDataUtils.checkIdResultUtils;
import static cn.hinglo.gameclaw.data.utils.FieldUtils.*;


/**
 * @createTime: 2018/1/2
 * @author: HingLo
 * @description: 订单管理类
 */
@Service
public class OderService {
    private final OrderDao orderDao;

    @Autowired
    public OderService(OrderDao orderDao) {
        this.orderDao = orderDao;
    }


    /***
     * 根据指定的订单类型返回订单信息
     * @param status 指定的订单状态
     * @return 返回值
     */
    public Result listOderService(int status, int page, int pageSize) {
        Page page1 = PageHelper.startPage(page, pageSize).setOrderBy("date desc");
        if (status == ORDER_0 || status == ORDER_1 || status == ORDER_2 || status == ORDER_4) {
            //指定的订单类型
            Orders orders = new Orders().setStatus(status);
            Map<String, Object> map = new HashMap<>(2);
            map.put("result", orderDao.select(orders));
            map.put("total", page1.getTotal());
            return ResultUtils.success(map);
            //全部订单信息
        } else if (status == ORDER_3) {
            Map<String, Object> map = new HashMap<>(2);
            map.put("result", orderDao.selectAll());
            map.put("total", page1.getTotal());
            return ResultUtils.success(map);
        } else {
            return ResultUtils.error("订单查询状态码错误");
        }
    }

    /**
     * 邮寄下单
     *
     * @param noteList  抓取记录集合
     * @param userId    用户的Id
     * @param addressId 发货地址的Id
     * @param payment   付款的方式
     * @return 订单信息
     */
    public Orders createOrderService(List<GrabNote> noteList, String userId, Long addressId, int payment) {
        StringBuilder body = new StringBuilder();
        noteList.forEach(x -> body.append(x.getCname()).append(","));
        String subject = "抓娃娃邮寄费用";
        Orders order = new Orders();
        order.setId(IdUtils.getOrderId());
        order.setSubject(subject);
        order.setUserId(userId);
        order.setAid(addressId);
        order.setDate(new Date());
        order.setBody(body.toString());
        order.setNum(noteList.size());
        order.setHeader(noteList.get(0).getHeader());

        //设置邮费
        if (noteList.size() >= FieldUtils.POSTAGE_NUM) {
            order.setMon(0);
            //设置订单状态为待发货
            order.setStatus(ORDER_0);
        } else {
            //设置订单状态为待付款
            order.setStatus(FieldUtils.ORDER_4);
            //设置邮费
            order.setMon(FieldUtils.POSTAGE);
        }
        order.setPayment(payment);
        if (orderDao.insert(order) == 1) {
            return order;
        } else {
            return null;
        }
    }

    /**
     * 删除订单信息
     *
     * @param id 订单的编号
     * @return 返回删除结果
     */
    public Result deleteOderService(String id) {
        //检测Id格式是否符合要求
        checkIdResultUtils(id);
        return orderDao.deleteByPrimaryKey(id) > 0 ? ResultUtils.success() : ResultUtils.error("删除失败");
    }


    /**
     * 标记订单的状态
     *
     * @param id     订单Id
     * @param status 状态
     * @return 标记结果
     */
    public Result endOderService(String id, int status) {

        //检测Id格式是否符合要求
        checkIdResultUtils(id);
        Orders orders = new Orders().setId(id).setStatus(status);
        //标记为发货中
        if (status == ORDER_1) {
            return orderDao.updateByPrimaryKeySelective(orders) > 0 ? ResultUtils.success() : ResultUtils.error("订单标记失败");
        } else if (status == ORDER_2) {
            //标记为完成的订单了，
            //之所以要分开出来，是因为，将来修改需要，若果订单多了，就要把完成的订单放在单独的表中，加快其他信息的查询
            return orderDao.updateByPrimaryKeySelective(orders) > 0 ? ResultUtils.success() : ResultUtils.error("订单标记失败");
        }

        //TODO 待实现的标记
        return ResultUtils.success();
    }

    /**
     * 标记订单为指定的状态为 待发货
     * <p> 主要是用在支付结果通知，如果支付成功后，就需要修改订单的状态为待发货的状态</p>
     *
     * @param orderId    订单编号
     * @param payDate    付款时间
     * @param payAccount 支付的方式
     * @return 返回并单标记结果
     */
    public boolean markOrderService(String orderId, Date payDate, Integer payAccount) {
        Orders orders = new Orders().setId(orderId).setPayDate(payDate).setPayment(payAccount).setStatus(ORDER_0);
        return orderDao.updateByPrimaryKeySelective(orders) == 1;

    }

    /**
     * 填写指定的待发货的物流订单的编号
     *
     * @param id  订单编号
     * @param gid 物流编号
     * @return 返回结果
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public Result updateGidService(String id, String gid) {
        if (StrUtil.isBlank(id) || StrUtil.isBlank(gid)) {
            return ResultUtils.error("订单或者物流编号不能为空");
        }

        //根据订单信息查询订单是否存在
        Orders orders1 = orderDao.selectByPrimaryKey(id);
        if (orders1 == null) {
            return ResultUtils.error("订单不存在");
        }
        //待更新的信息
        Orders orders = new Orders().setId(id).setGid(gid).setStatus(ORDER_1);
        if (orderDao.updateByPrimaryKeySelective(orders) == 1) {
            return ResultUtils.success();
        } else {
            throw new RuntimeException("物流订单标记失败");
        }
    }

    /**
     * 查询指定类型指定时间的物理费用明细
     *
     * @param type 支付类型
     * @param date 时间
     * @return 返回结果
     */
    public Result orderDetailService(int type, Date date) {
        if (type < 1) {
            type = FieldUtils.PAYMENT_1;
        }
        if (date == null) {
            date = DateUtil.offsetDay(new Date(), -1);
        }
        return ResultUtils.success(orderDao.orderDetailDao(type, date));

    }
}
